home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / dice-3.16.lha / examples / DosHan / main.c < prev    next >
C/C++ Source or Header  |  1998-09-27  |  7KB  |  313 lines

  1.  
  2. /*
  3.  *  MAIN.C
  4.  *
  5.  *  MAIN FOR DOS HANDLER TEST PROGRAM FOR DICE
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <exec/nodes.h>
  10. #include <exec/ports.h>
  11. #include <exec/memory.h>
  12. #include <dos/dos.h>
  13. #include <dos/dosextens.h>
  14. #include <dos/filehandler.h>
  15.  
  16. #include <clib/exec_protos.h>
  17. #include <clib/alib_protos.h>
  18. #include <lists.h>
  19.  
  20. #include <stdio.h>
  21. #include <stdarg.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24.  
  25. #define DOS_TRUE    -1
  26. #define DOS_FALSE   0
  27.  
  28. #define BTOC(bptr)  ((void *)((long)(bptr) << 2))
  29. #define CTOB(cptr)  ((BPTR)(((long)cptr) >> 2))
  30.  
  31. typedef struct DosPacket    DosPacket;
  32. typedef struct FileHandle   FileHandle;
  33. typedef struct DeviceNode   DeviceNode;
  34. typedef struct Process        Process;
  35. typedef struct Node        Node;
  36. typedef struct List        List;
  37. typedef struct MsgPort        MsgPort;
  38. typedef struct Message        Message;
  39.  
  40. typedef struct XHandle {
  41.     Node    xh_Node;
  42.     long    xh_XHLen;
  43.     long    xh_Refs;
  44.     long    xh_Flags;
  45.     List    xh_List;
  46. } XHandle;
  47.  
  48. #define XHF_EOF     0x0001
  49.  
  50. typedef struct XNode {
  51.     Node    xn_Node;
  52.     char    *xn_Buf;
  53.     long    xn_Offset;
  54.     long    xn_Length;
  55. } XNode;
  56.  
  57. void returnpacket(DosPacket *);
  58. void Initialize(void);
  59. void UnInitialize(void);
  60.  
  61.  
  62. List    HanList;
  63. DeviceNode *DevNode;
  64. MsgPort    *PktPort;
  65.  
  66. /*
  67.  *  Note that we use the _main entry point.  Also notice that we do not
  68.  *  need to open any libraries.. they are openned for us via DICE's
  69.  *  unique auto-library-open ability.
  70.  */
  71.  
  72. void
  73. _main()
  74. {
  75.     DosPacket  *packet;
  76.  
  77.     {
  78.     Process *proc = (struct Process *)FindTask(NULL);
  79.     PktPort = &proc->pr_MsgPort;
  80.     }
  81.     NewList(&HanList);
  82.     Initialize();
  83.  
  84.     /*
  85.      *    Main Loop
  86.      */
  87.  
  88.     for (;;) {
  89.     {
  90.         Message *msg;
  91.  
  92.         while ((msg = GetMsg(PktPort)) == NULL)
  93.         Wait(1 << PktPort->mp_SigBit);
  94.         packet = (DosPacket *)msg->mn_Node.ln_Name;
  95.     }
  96.  
  97.     /*
  98.      *  default return value
  99.      */
  100.  
  101.     packet->dp_Res1 = DOS_TRUE;
  102.     packet->dp_Res2 = 0;
  103.  
  104.     /*
  105.      *  switch on packet
  106.      */
  107.  
  108.     switch(packet->dp_Type) {
  109.     case ACTION_DIE:        /*    ??? */
  110.         break;
  111.     case ACTION_FINDUPDATE:     /*    FileHandle,Lock,Name        Bool    */
  112.     case ACTION_FINDINPUT:        /*    FileHandle,Lock,Name        Bool    */
  113.     case ACTION_FINDOUTPUT:     /*    FileHandle,Lock,Name        Bool    */
  114.         {
  115.         FileHandle *fh = BTOC(packet->dp_Arg1);
  116.         XHandle *xh;
  117.  
  118.         {
  119.             unsigned char *base = BTOC(packet->dp_Arg3);
  120.             int len = *base;
  121.             char buf[128];
  122.  
  123.             if (len >= sizeof(buf))
  124.             len = sizeof(buf) - 1;
  125.  
  126.             strncpy(buf, base + 1, len);
  127.             buf[len] = 0;
  128.  
  129.             if ((xh = (XHandle *)FindName(&HanList, buf)) == NULL) {
  130.             xh = AllocMem(sizeof(XHandle) + len + 1, MEMF_PUBLIC | MEMF_CLEAR);
  131.             xh->xh_XHLen = sizeof(XHandle) + len + 1;
  132.             xh->xh_Node.ln_Name = (char *)(xh + 1);
  133.             movmem(buf, xh->xh_Node.ln_Name, len + 1);
  134.             NewList(&xh->xh_List);
  135.             AddTail(&HanList, &xh->xh_Node);
  136.             }
  137.             ++xh->xh_Refs;
  138.         }
  139.         fh->fh_Arg1 = (ULONG)xh;
  140.         fh->fh_Port = (MsgPort *)DOS_TRUE;
  141.         }
  142.         break;
  143.     case ACTION_READ:        /*    FHArg1,CPTRBuffer,Length    ActLength    */
  144.         /*
  145.          *    reading is straightforward except for handling EOF ... we
  146.          *    must guarentee a return value of 0 (no bytes left) before
  147.          *    beginning to return EOFs (-1's).  If we return a negative
  148.          *    number right off programs like COPY will assume a failure
  149.          *    (if TEST: is the source) and delete the destination file
  150.          */
  151.  
  152.         {
  153.         XHandle *xh = (XHandle *)packet->dp_Arg1;
  154.         long bytes;
  155.  
  156.         packet->dp_Res1 = 0;
  157.         while ((bytes = packet->dp_Arg3 - packet->dp_Res1) > 0) {
  158.             XNode *xn = (XNode *)RemHead(&xh->xh_List);
  159.  
  160.             if (xn == NULL)
  161.             break;
  162.  
  163.             if (bytes > xn->xn_Length - xn->xn_Offset)
  164.             bytes = xn->xn_Length - xn->xn_Offset;
  165.             movmem(xn->xn_Buf + xn->xn_Offset, (char *)packet->dp_Arg2 + packet->dp_Res1, bytes);
  166.  
  167.             xn->xn_Offset += bytes;
  168.             packet->dp_Res1 += bytes;
  169.             if (xn->xn_Offset == xn->xn_Length) {
  170.             FreeMem(xn->xn_Buf, xn->xn_Length);
  171.             FreeMem(xn, sizeof(XNode));
  172.             } else {
  173.             AddHead(&xh->xh_List, &xn->xn_Node);
  174.             }
  175.         }
  176.         if (packet->dp_Res1 == 0 && GetHead(&xh->xh_List) == NULL) {
  177.             if (xh->xh_Flags & XHF_EOF)
  178.             packet->dp_Res1 = -1;    /*  EOF */
  179.             xh->xh_Flags |= XHF_EOF;
  180.         }
  181.         }
  182.         break;
  183.     case ACTION_WRITE:        /*    FHArg1,CPTRBuffer,Length    ActLength    */
  184.         {
  185.         XHandle *xh = (XHandle *)packet->dp_Arg1;
  186.         XNode *xn;
  187.         long bytes = packet->dp_Arg3;
  188.  
  189.         packet->dp_Res1 = -1;
  190.         if (xn = AllocMem(sizeof(XNode), MEMF_PUBLIC|MEMF_CLEAR)) {
  191.             if (xn->xn_Buf = AllocMem(bytes, MEMF_PUBLIC)) {
  192.             movmem((char *)packet->dp_Arg2, xn->xn_Buf, bytes);
  193.             xn->xn_Length = bytes;
  194.             packet->dp_Res1 = bytes;
  195.             AddTail(&xh->xh_List, &xn->xn_Node);
  196.             xh->xh_Flags &= ~XHF_EOF;
  197.             } else {
  198.             FreeMem(xn, sizeof(XNode));
  199.             packet->dp_Res2 = ERROR_NO_FREE_STORE;
  200.             }
  201.         } else {
  202.             packet->dp_Res2 = ERROR_NO_FREE_STORE;
  203.         }
  204.         }
  205.         break;
  206.     case ACTION_END:        /*    FHArg1                Bool:TRUE    */
  207.         {
  208.         XHandle *xh = (XHandle *)packet->dp_Arg1;
  209.  
  210.         if (--xh->xh_Refs == 0 && GetHead(&xh->xh_List) == NULL) {
  211.             Remove(&xh->xh_Node);
  212.             FreeMem(xh, xh->xh_XHLen);
  213.         }
  214.         break;
  215.         }
  216.         break;
  217.     default:
  218.         packet->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
  219.         break;
  220.     }
  221.     if (packet) {
  222.         if (packet->dp_Res2)
  223.         packet->dp_Res1 = DOS_FALSE;
  224.         returnpacket(packet);
  225.     }
  226.     }
  227.  
  228.     /*
  229.      *    no reached
  230.      */
  231.  
  232.     UnInitialize();
  233.     _exit(0);
  234. }
  235.  
  236.  
  237. /*
  238.  *  PACKET ROUTINES.    Dos Packets are in a rather strange format as you
  239.  *  can see by this and how the PACKET structure is extracted in the
  240.  *  GetMsg() of the main routine.
  241.  */
  242.  
  243. void
  244. returnpacket(packet)
  245. DosPacket *packet;
  246. {
  247.     Message *mess;
  248.     MsgPort *replyPort;
  249.  
  250.     replyPort             = packet->dp_Port;
  251.     mess             = packet->dp_Link;
  252.     packet->dp_Port         = PktPort;
  253.     mess->mn_Node.ln_Name    = (char *)packet;
  254.     PutMsg(replyPort, mess);
  255. }
  256.  
  257. /*
  258.  *  During initialization DOS sends us a packet and sets our dn_SegList
  259.  *  pointer.  If we set our dn_Task pointer than every Open's go to the
  260.  *  same handler (this one).  If we set dn_Task to NULL, every Open()
  261.  *  will create a NEW instance of this process via the seglist, meaning
  262.  *  our process must be reentrant (i.e. -r option).
  263.  *
  264.  *  note: dn_Task points to the MESSAGE PORT portion of the process
  265.  *  (or your own custom message port).
  266.  *
  267.  *  If we clear the SegList then we also force DOS to reload our process
  268.  *  from disk, but we also need some way of then UnLoadSeg()ing it ourselves,
  269.  *  which we CANNOT do from this process since it rips our code out from
  270.  *  under us.
  271.  */
  272.  
  273. void
  274. Initialize()
  275. {
  276.     DeviceNode *dn;
  277.     Process *proc = (Process *)FindTask(NULL);
  278.     DosPacket *packet;
  279.  
  280.     /*
  281.      *    Handle initial message.
  282.      */
  283.  
  284.     {
  285.     Message *msg;
  286.  
  287.     WaitPort(PktPort);
  288.     msg = GetMsg(PktPort);
  289.     packet = (DosPacket *)msg->mn_Node.ln_Name;
  290.     }
  291.  
  292.     {
  293.     DevNode = dn = BTOC(packet->dp_Arg3);
  294.  
  295.     dn->dn_Task = PktPort;
  296.     }
  297.     packet->dp_Res1 = DOS_TRUE;
  298.     packet->dp_Res2 = 0;
  299.     returnpacket(packet);
  300. }
  301.  
  302. void
  303. UnInitialize(void)
  304. {
  305.     {
  306.     DeviceNode *dn = DevNode;
  307.  
  308.     dn->dn_Task = NULL;
  309.     /* dn->dn_SegList = NULL; */
  310.     }
  311. }
  312.  
  313.